//******************************************************************************
//this code is protected by the GNU affero GPLv3
//author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
//                        <digital.ragnarok AT gmail dot com>
//******************************************************************************
//------------------------------------------------------------------------------
//compiler stuff
//------------------------------------------------------------------------------
#include <stdarg.h>
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//ulinux stuff
//------------------------------------------------------------------------------
#include <ulinux/compiler_types.h>
#include <ulinux/types.h>
#include <ulinux/sysc.h>
#include <ulinux/error.h>

#include <ulinux/utils/ascii/ascii.h>
#include <ulinux/utils/ascii/string/string.h>
#include <ulinux/utils/ascii/string/vsprintf.h>
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//protocol
//------------------------------------------------------------------------------
#include <wayland/display.h>
#include <wayland/callback.h>
#include <wayland/compositor.h>
#include <wayland/registry.h>
#include <wayland/shm.h>
#include <wayland/shm_pool.h>
#include <wayland/buffer.h>
#include <wayland/seat.h>
#include <wayland/output.h>
#include <wayland/keyboard.h>
#include <wayland/pointer.h>
#include <wayland/wayland.h>
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//our private stuff
//------------------------------------------------------------------------------
#include "globals.h"
#include "objs.h"
#include "srv/display.h"
#define REGISTRY_C
#include "srv/registry.h"
#undef REGISTRY_C
#include "wire/wl_registry.h"
//------------------------------------------------------------------------------

static k_u32 registry_id;

void registry_add(k_u32 name,enum wl_itfs itf)
{
  k_u i;
  for(i=0;i<REGISTRY_N_MAX;++i) if(registry[i].itf==WL_INVALID) break;
  if(i==REGISTRY_N_MAX){
    PERR("FATAL:no room for global object name=%u interface=%s\n",name,
                                                             wl_itfs_strs[itf]);
    sysc(exit_group,1,-1);
  }
  //DEBUG
  PERR("registry:adding object name=%u itf=%s\n",name,wl_itfs_strs[itf]);
  registry[i].itf=itf;
  registry[i].name=name;
}

void registry_del(k_u32 name)
{
  k_u i;
  for(i=0;i<REGISTRY_N_MAX;++i) if(registry[i].name==name) break;
  if(i==REGISTRY_N_MAX) return;//object not found
  registry[i].itf=WL_INVALID;
}

static void ev_global(k_u32 name,enum wl_itfs itf)
{
  registry_add(name,itf);
}

static void ev_global_remove(k_u32 name)
{
  registry_del(name);
}

static struct wl_registry_listener listener={
  .global=ev_global,
  .global_remove=ev_global_remove
};

void registry_init(void)
{
  for(k_u i=0;i<REGISTRY_N_MAX;++i) registry[i].itf=WL_INVALID;
}

void registry_get(void)
{
  registry_id=display_get_registry((void*)&listener);
}

k_u32 registry_bind(struct gbl *g,void *listener)
{
  k_u32 g_id=objs_add(g->itf,listener);
  if(g_id==OBJS_MAX){
    PERRC("FATAL:registry::bind unable to add the object\n");
    sysc(exit_group,1,-1);
  }

  wl_registry_req_bind(registry_id,g,g_id);
  return g_id;
}
